﻿using _404park.Core.Crawler;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace _404park.ApplicationServices.Crawler.Parser.Provider
{
    public class BingParser : BaseFeedParser
    {
        private static readonly string accountKey = "HyDi1WRtrmcNFOc2rsL9zTEQSl6XLcEQs8ihtRuJT4o";

        public override string BaseUrl
        {
            get
            {
                return "https://api.datamarket.azure.com/Bing/Search/v1/Composite?Sources=%27web%27&Query=%27{0}%27&$skip={1}";
            }
        }

        internal override string GetFeedUrl(string keyword, int start = 0)
        {
            return string.Format(BaseUrl, keyword, start*100);
        }

        public override string GetRawResult(string requestUri, int connectionTimeout, int readTimeout)
        {
            string responseData = string.Empty;
            var user_agent = "PowerSearch/1.0";

            var webClient = new TimeOutWebClient(connectionTimeout);
            webClient.Credentials = new NetworkCredential(accountKey, accountKey);
            webClient.Headers.Add("user-agent", user_agent);

            using (var responseStream = webClient.OpenRead(requestUri))
            {
                if (responseStream != null)
                {
                    var responseReader = new StreamReader(responseStream);
                    responseData = responseReader.ReadToEnd();
                }
            }

            return responseData;
        }

        protected internal override IList<Feed> ParseFeed(string data)
        {
            var feedList = new List<Feed>();
            var xmlDoc = XDocument.Parse(data);
            var defaultNamespace = xmlDoc.Root.GetDefaultNamespace();
            var mNamespace = xmlDoc.Root.GetNamespaceOfPrefix("m");
            var dNamespace = xmlDoc.Root.GetNamespaceOfPrefix("d");
            if (xmlDoc.Root != null)
            {
                xmlDoc.Root.Descendants(defaultNamespace + "entry").ToList().ForEach(element => {
                    var feed = CreateFeedItem(element, defaultNamespace, mNamespace, dNamespace);
                    if (feed != null && !string.IsNullOrEmpty(feed.Title))
                        feedList.Add(feed);
                });
            }
            return feedList;
        }

        private Feed CreateFeedItem(XElement xElement, XNamespace defaultNamespace, XNamespace mNamespace, XNamespace dNamespace)
        {
            var contentElement = xElement.Element(defaultNamespace + "content");
            if (contentElement == null) return null;

            var propertyElement = contentElement.Element(mNamespace + "properties");
            if (propertyElement == null) return null;

            var title = propertyElement.Element(dNamespace + "Title") != null ? propertyElement.Element(dNamespace + "Title").Value : string.Empty;
            var description = propertyElement.Element(dNamespace + "Description") != null ? propertyElement.Element(dNamespace + "Description").Value : string.Empty;
            var clickUrl = propertyElement.Element(dNamespace + "Url") != null ? propertyElement.Element(dNamespace + "Url").Value : string.Empty;
            var updateDate = xElement.Element(defaultNamespace + "updated") != null ? xElement.Element(defaultNamespace + "updated").Value : string.Empty;

            var feed = new Feed
            {
                Title = title,
                Description = description,
                ClickUrl = clickUrl,
                UpdateDate = updateDate
            };
            return feed;
        }

    }
}
